Enkstein
A modular zero-trust security ecosystem built to govern every security action — from AI prompt evaluation to cloud posture remediation — through a single, auditable enforcement layer.
What is Enkstein?
Enkstein is a distributed security and AI workspace organized around the principle that every action must be authorized, every decision must be attributable, and no component is trusted by default.
The platform is composed of three interconnected layers:
- 26 Capability Nodes + core control surfaces — Specialized domain modules cover AI security, cloud posture, identity governance, endpoint detection, compliance, DLP, Terraform/IaC governance, and more. Model Cortex, Command, and Release Governance sit beside them as governed platform surfaces for model routing, command intake, and deployment preflight.
- Trust Fabric — The central policy service for governed actions: anomaly detection, policy evaluation, risk scoring, audit context, and decision. Includes Execution Ring Policy (ring0–ring3 privilege isolation) and SRE Engine (circuit breaker, error budget).
- CoreOS — The orchestration layer managing agents, Swarm multi-agent jobs, multi-step workflows, event-driven triggers, scheduled jobs, Channel Gateway command ingestion, and human approval flows with dual-approval enforcement.
Three runtime subsystems give Capability Nodes bounded independence rather than routing every decision through a central dispatcher:
- Plexus — governed peer messaging between Nodes. A participant identity is required, messages can be held for approval, and metadata is verified on read and acknowledgement.
- Reflexes — policy-bounded local autonomy. A Node evaluates an incoming event against its registered reflexes and may act within its bounds, with every decision written to an execution log.
- Regeneration — signed Node checkpoints and governed regeneration runs, so a Capability Node can be restored from a verified checkpoint rather than rebuilt by hand.
Key Design Decisions
- Modular capability nodes — add, disable, or extend security domains without touching the core.
- Provider-agnostic — each Capability Node ships with adapters for multiple providers (e.g., Cloud Security supports AWS, Azure, GCP).
- Async-first backend — FastAPI with async SQLAlchemy; long-running scans do not block the event loop.
- Attributable audit records — Trust Fabric decisions record available actor, policy, risk, and outcome context.
- Human-in-the-loop — configurable approval gates mean humans remain in control of high-risk actions.
Platform at a Glance
| Component | Purpose | Key Tech |
|---|---|---|
| Backend API | Security data, policy evaluation, orchestration | FastAPI, SQLAlchemy, PostgreSQL |
| Frontend | Security dashboards, claw UIs, workflow builder | Next.js 14, TypeScript, Tailwind |
| Trust Fabric | Zero-trust enforcement pipeline | Custom policy engine, Redis |
| CoreOS | Agent orchestration, scheduling, approvals | Python workers, event bus |
| CLI | Administrative tooling | Python typer |
Quick Start
Start a local Enkstein evaluation environment with Docker Compose.
Downloadable Package
Versioned GitHub Releases include .tar.gz and .zip self-hosted bundles, Python wheels/source distributions, and a SHA256SUMS integrity file. Extract the bundle and run ./install.sh. The installer validates Docker Compose, creates unique installation secrets without overwriting an existing .env, and starts the production Compose stack.
tar -xzf enkstein-VERSION.tar.gz
cd enkstein-VERSION
./install.sh
Native Installers
Desktop users can install Enkstein-VERSION-macos.pkg or Enkstein-VERSION-windows-x64-setup.exe. These packages create an Enkstein launcher that starts Docker Desktop, initializes secrets, and starts the governed runtime. The universal macOS app shows startup progress, waits for backend and frontend health, and embeds Enkstein in a native WebKit window instead of opening the browser. Docker Desktop remains a prerequisite. Published macOS packages are Developer ID signed and released after Apple notarization; public Windows installers remain unsigned until Authenticode signing is configured.
Persistent Chat and Cowork
Enkstein provides encrypted tenant-scoped conversations, searchable history, branches, and Cowork Projects. The desktop shell can grant a project access to one selected local folder through an opaque native token; raw host paths never enter the container or web UI. Bounded text files become persistent Cowork context and can be created, edited, renamed, moved, synchronized, or sent to recoverable project trash. Browser Cowork keeps an import-copy fallback. Mutations are tenant-scoped and Trust Fabric authorized, with traversal and symlink defenses at the native boundary. Auto Brain routing records its candidates, attempts, selected source, and policy reason. A conversation can be handed to an approval-gated Security Swarm without copying plaintext conversation content into the Swarm record.
POST /api/v1/marcellus/workspace/projects
POST /api/v1/marcellus/workspace/conversations
POST /api/v1/marcellus/workspace/conversations/{id}/turns
POST /api/v1/marcellus/workspace/conversations/{id}/branches
POST /api/v1/marcellus/workspace/conversations/{id}/security-investigation
Plexus, Reflexes, and Regeneration
Capability Nodes are not purely centrally dispatched. Plexus carries governed peer messages between Nodes: a participant identity is required, a message can be held for approval before delivery, and metadata is verified on read and acknowledgement. Reflexes give a Node policy-bounded local autonomy — an incoming event is evaluated against its registered reflexes and may be acted on within its bounds, with every decision written to an execution log. Regeneration captures signed Node checkpoints and runs governed restores, so a Node can be rebuilt from a verified checkpoint. All three are tenant-scoped and Trust Fabric authorized.
POST /api/v1/marcellus/plexus/messages
GET /api/v1/marcellus/plexus/inbox/{node_id}
POST /api/v1/marcellus/plexus/messages/{message_id}/approve
POST /api/v1/marcellus/plexus/messages/{message_id}/ack
POST /api/v1/marcellus/reflexes
POST /api/v1/marcellus/reflexes/evaluate
GET /api/v1/marcellus/reflexes/executions
POST /api/v1/marcellus/regeneration/checkpoints
POST /api/v1/marcellus/regeneration/runs
Prerequisites
- Docker Desktop 24+ and Docker Compose v2
- Python 3.12+ (for seed scripts and CLI)
- Git
- 4 GB RAM minimum (8 GB recommended)
Enkstein stores connector credentials encrypted on your machine. Never commit the
backend/.secrets/ folder to git — it contains your encryption key. It is gitignored by default. Each deployment generates its own isolated key on first run. Do not share or publish this folder.
1. Clone and Configure
git clone https://github.com/wcoreiron-rgb/enkstein cd enkstein cp .env.example .env # Set SECRET_KEY and DB password
Open .env and configure at minimum:
POSTGRES_USER=enkstein POSTGRES_PASSWORD=your-secure-password POSTGRES_DB=enkstein SECRET_KEY=your-jwt-secret-key REDIS_URL=redis://localhost:6379
2. Start Services
docker compose up --build -d # Verify all containers are healthy docker compose ps
This starts four containers: backend (FastAPI on port 8000), frontend (Next.js production server on port 3000), postgres, and redis.
npm run build during build and npm run start at runtime. Browser /api/v1/* calls are proxied to http://backend:8000 inside the Compose network.
3. Seed the Database
Seed scripts populate Enkstein with example data for policies, agents, connectors, workflows, and more. Run them once after a fresh install:
cd backend # Core configuration python seed_policies.py python seed_connectors.py python seed_agents.py python seed_workflows.py # Memory, profiles, and skill packs python seed_memory.py python seed_profiles.py python seed_skill_packs.py # Event system python seed_triggers.py python seed_policy_packs.py # Channel and execution infrastructure python seed_channel_gateway.py python seed_exec_channels.py python seed_exchange.py # Example orchestration scenarios python seed_example_orchestrations.py
4. Access the Platform
| Service | URL | Notes |
|---|---|---|
| Frontend | http://localhost:3000 | Main security dashboard |
| API | http://localhost:8000 | REST API base |
| API Docs | http://localhost:8000/docs | Interactive Swagger UI |
| API Schema | http://localhost:8000/redoc | ReDoc documentation |
ADMIN_EMAIL / ADMIN_PASSWORD from their private .env; there is no public default password.
5. Add Your Own API Credentials
Capability Nodes require a configured connector for live evidence. Some legacy workflows can expose clearly labelled demonstration data for evaluation; demo evidence is never presented as a verified estate result or a passing control verdict. Add your environment through the Connectors page:
- Open Connectors
Go tohttp://localhost:3000/connectorsand find the integration you want to connect. - Click Configure
A modal opens asking for your API key, token, or OAuth credentials — whatever that integration requires. - Enter your credentials
Credentials are encrypted before being stored in the local secret volume and are not written to logs. Enkstein sends them only to the configured provider endpoint when that connector authenticates; it does not send connector credentials to model providers. - Test the connection
Enkstein makes a real read-only API call to verify your credentials work. On success, the connector status turns green and the corresponding Capability Node begins pulling real findings.
| Capability Node | Supported integrations | Credentials needed |
|---|---|---|
| Cloud Security | AWS, Azure, GCP | Access key + secret / Service principal / Service account JSON |
| Endpoint Security | CrowdStrike, Defender, SentinelOne | Client ID + secret / API token |
| Privileged Access | Okta, Microsoft Entra ID, AWS IAM | API token / Client credentials |
| Model Cortex | Codex/Claude host bridges, NVIDIA NIM, Gemini, Anthropic, OpenAI, Azure OpenAI, Ollama | Approved bridge, API key, or local runtime |
| Developer Security | GitHub | Personal access token (read: security_events, code) |
| Security Telemetry | Splunk | HEC token + host |
| Custom Capability | Any REST API | Bearer token, API key header, or none |
simulated and cannot become a live control verdict.
Stopping and Resetting
# Stop services (keep data) docker compose stop # Full reset — removes all data ./reset.sh
Architecture
Enkstein uses a containerized microservice architecture with a clear separation between the security data layer, trust enforcement, orchestration, and presentation.
System Overview
┌─────────────────────────────────────────────────────┐
│ Frontend (Next.js 14) │
│ Security Dashboards · Capability Node UIs · Workflows │
└──────────────────────┬──────────────────────────────┘
│ REST / WebSocket
┌──────────────────────▼──────────────────────────────┐
│ FastAPI Backend │
│ ┌──────────┐ ┌─────────────┐ ┌───────────────┐ │
│ │ 26 Nodes │ │ Trust Fabric│ │ CoreOS │ │
│ │ Routes │ │ Pipeline │ │Swarm/Cmd/Sched│ │
│ └────┬─────┘ └──────┬──────┘ └───────┬───────┘ │
│ └───────────────┼──────────────────┘ │
│ │ │
│ ┌────────────────────▼───────────────────────┐ │
│ │ SQLAlchemy 2.0 (async ORM) │ │
│ └──────────┬──────────────────┬──────────────┘ │
└──────────────┼──────────────────┼───────────────────┘
│ │
┌──────────▼──────┐ ┌───────▼────────┐
│ PostgreSQL │ │ Redis │
│ Primary store │ │ Cache · Pub/Sub│
└─────────────────┘ └────────────────┘
Backend
The FastAPI backend exposes a versioned REST API under /api/v1/ and organizes routes by Capability Node and platform feature:
- Capability Node routers —
/app/claws/{name}/routes.py— Node routers commonly expose/stats,/findings,/providers,/scan, and/task; consult OpenAPI for the exact surface. - Trust Fabric —
/app/trust_fabric/— shared policy and risk services used by governed Node actions. - CoreOS —
/app/core/— agent execution, workflow DAGs, trigger evaluation, scheduling. - Auth — bearer-token authentication with local owner password and TOTP enrollment for desktop installs.
Database
PostgreSQL is the primary data store. Schema migrations are managed with Alembic. Key schema groups:
- Findings tables — one per Capability Node, normalized to a common findings schema.
- Policy tables — policies, policy packs, evaluation results.
- Audit tables — tenant-scoped Trust Fabric decision records.
- CoreOS tables — agents, workflows, triggers, schedules, approvals.
Frontend
Built with the Next.js App Router. Capability Nodes and shared control surfaces are presented through route-specific pages under /src/app/. Shared components live in /src/components/.
How the Trust Fabric Works
The Trust Fabric is the policy and risk core for governed Enkstein actions. Covered execution paths provide actor, target, policy, risk, decision, and audit context before execution.
The Six Stages
-
Action Request A governed security action enters the Trust Fabric with a context payload: actor identity, action type, target resource, Node origin, and metadata.
-
Anomaly Detection The behavioral baseline engine evaluates the request against historical patterns for the actor and action type. Unusual timing, frequency, or target patterns raise the initial risk signal before policies run.
-
Policy Evaluation The policy engine evaluates all applicable policies — organizational, Node-specific, and compliance-driven — in priority order. Policies can allow, deny, or escalate. Policy pack groupings let you apply compliance frameworks (SOC 2, ISO 27001) as a unit.
-
Risk Scoring A composite risk score is computed from anomaly signals, policy outcomes, actor trust level, and resource sensitivity. The score maps to a required authorization level (none, log-only, approval-required, or blocked).
-
Audit Log The available evaluation context is written to the audit record with the decision, so an operator can reconstruct the policy inputs and recorded outcome later.
-
Decision The final decision is one of:
ALLOW,DENY,ESCALATE(route to approval flow), orCONTAIN(emergency isolation). The decision is returned to the caller and logged.
Policy Engine
Enkstein's policy engine evaluates structured rules against action context to produce allow/deny/escalate decisions. Policies are stored in PostgreSQL and can be updated without restarting the platform.
Policy Structure
Each policy has:
- Name and description
- Priority — lower number = evaluated first
- Conditions — JSON-encoded predicate tree (actor, action, resource, time, risk score)
- Effect —
ALLOW,DENY, orESCALATE - Scope — global, Node-specific, or per-actor-type
- Enabled flag — toggle without deleting
Policy Packs
Policy packs are curated bundles of policies aligned to a compliance framework. Seeded packs include:
| Pack | Controls | Description |
|---|---|---|
| SOC 2 Type II | CC6, CC7, CC8 | Security and change management controls |
| ISO 27001 | A.9, A.12, A.16 | Access control, operations, incident management |
| NIST CSF | ID, PR, DE, RS, RC | Full cybersecurity framework coverage |
| CIS Benchmarks | L1/L2 | Infrastructure hardening baselines |
| Zero Trust Baseline | Custom | Enkstein's built-in zero-trust policy set |
Creating a Policy
POST /api/v1/policies/ Content-Type: application/json { "name": "Deny weekend remediations", "priority": 10, "effect": "ESCALATE", "conditions": { "action_type": "REMEDIATION", "time_window": "WEEKEND" }, "scope": "global", "enabled": true }
Anomaly Detection
Enkstein's behavioral anomaly detection engine runs before policy evaluation, raising risk signals for unusual patterns that policies alone may not catch.
How Baselines Work
For each actor (user, agent, service account) and each action type, the engine maintains rolling behavioral baselines stored in Redis:
- Frequency baseline — typical rate of a given action per hour/day
- Temporal baseline — time-of-day and day-of-week patterns
- Target baseline — which resources the actor typically acts on
- Volume baseline — typical number of resources affected per action
Deviations beyond configurable thresholds increment the risk score passed to the policy engine.
Anomaly Signals
| Signal | Description | Risk Delta |
|---|---|---|
| Off-hours activity | Action outside actor's normal active window | +10–25 |
| Frequency spike | Action rate 3x+ above baseline | +20–40 |
| Novel target | Resource not previously accessed by this actor | +15–30 |
| Bulk operation | Volume 5x+ above actor's typical batch size | +25–50 |
| Cross-Node correlation | Similar anomalies across multiple capability nodes simultaneously | +30–60 |
Execution Modes
Enkstein supports five execution modes that control how the Trust Fabric responds to a given action. Modes can be set globally, per Capability Node, or per workflow step.
Configuring Modes
Modes are configured per registered agent and bounded by the platform autonomy ceiling:
PATCH /api/v1/autonomy/agents/{agent_id}/mode { "mode": "approval" }
For emergency activation:
POST /api/v1/autonomy/emergency/activate { "reason": "Active incident — suspected data exfiltration" }
AGT Rollout & Swarm
Enkstein integrates AGT through a provider adapter boundary and feature flags. This allows staged rollout without coupling every Capability Node directly to AGT internals.
/triggers/{id}/test execution and start_swarm/fire_swarm action configuration, Swarm detail now includes live ticket draft + compliance rollup with direct Create Ticket handoff to /api/v1/remediation/trigger, channel ingress is normalized to the Command command contract, and execution/remediation routes now fail closed when Trust Fabric policy evaluation is unavailable.
Adapter Boundary
AGT integration is isolated under:
backend/app/fabric/providers/agt/ ├── adapter.py ├── version.py └── __init__.py
Capability Nodes and API routes call Regent Fabric interfaces, not AGT SDK APIs directly.
Feature Flags
AGT_VERSION_MODE=v1_compat AGT_ENABLE_AGENT_MESH=false AGT_ENABLE_E2E_MESSAGING=false AGT_ENABLE_MCP_GATEWAY=false AGT_ENABLE_SHADOW_DISCOVERY=false
Flags are configured via backend/.env. Roll out one capability at a time.
New Trust Fabric Endpoints
Command + Channel Gateway Convergence
Inbound channel messages are now normalized into a unified command payload and evaluated through the same governance path as direct Command requests.
- Ingress routes:
POST /api/v1/channel-gateway/slack/events,POST /api/v1/channel-gateway/teams/webhook,POST /api/v1/channel-gateway/message. - Additional adapters:
POST /api/v1/channel-gateway/webhookandPOST /api/v1/channel-gateway/email/inboundnow route external webhook/email requests into the same command contract. - CLI adapter:
POST /api/v1/channel-gateway/cli/commandroutes terminal-originated commands through the same path, with optional inline tenant metadata. - Normalization target: Command contract shape used by
POST /api/v1/commands(command_id,source,requester,tenant_id,intent,target,scope,mode). - Response metadata: channel message responses now include
command_resultwith policy outcome and command identifiers for traceability. - Outbound replies: configured Slack/Teams webhooks now receive status-update cards. Approval-required responses include approve/reject action metadata and Slack thread metadata when the inbound event supplies
thread_ts. - Operator visibility: persisted message detail exposes
response_sent,outbound_delivery, andoutbound_card. Control Center also reports 24-hour sent/pending-config reply counts. - Simulation parity:
POST /api/v1/channel-gateway/simulatenow runs the same normalization and returnscommand_resultfor dry-run validation. - Graceful fallback: when async command backend is unavailable, channel ingestion remains non-breaking and returns
outcome: unavailable.
Remote Agent Dispatch Safeguards
- Tenant boundary: dispatch requests are denied when command
tenant_iddoes not match agent tenant metadata. - Heartbeat freshness gate: dispatch requests are denied when agent heartbeat is stale beyond the configured TTL.
- Trust gate: dispatch requires remote-agent trust score at or above configured minimum threshold.
- Kill switch enforcement: dispatch is blocked when remote agent kill switch is active.
- Intent allowlist: each remote agent can restrict allowed command intents via its metadata
allowed_actions. - Path/body consistency: dispatch rejects mismatched
remote_agent_idvalues between route and payload.
Memory Cortex Runtime Review
High-risk Swarm Judge outputs can create proposed incident memory. Proposed memory is kept in review state until analysts approve or reject it, and approved memory can be rolled back if it should no longer influence runtime context.
Command Approval Workflow APIs
Commands that resolve to approval-required outcomes can now be tracked and approved via Command endpoints.
Frontend support is now available on /channel-gateway with a dedicated Pending Commands tab and in-page approval actions.
- Self-approval guard: requester identity cannot approve its own pending command.
- Duplicate guard: same approver cannot approve the same command twice.
- Principal binding: approvals/rejections are bound to authenticated JWT identity; request-body display names are non-authoritative.
- Multi-operator finalization: command is marked allowed only after required approvals are satisfied; intermediate approvals remain pending.
- Explicit rejection path: pending commands can be terminated as blocked with reviewer attribution and reason persisted.
- Timeline trail: command lifecycle events are queryable for operator review and exposed in Channel Gateway command rows.
- Timeline focus filters: operator panel supports All/Approvals/Rejections views to cut audit noise.
- Timeline export: operators can copy/download command timeline JSON for audit handoff.
- Approval audit summary: command status now includes latest approver principal/display and rejection principal metadata for operator review.
- Pending filters: pending list supports source/requester/min-risk filtering for operational triage.
- Delegated approval thresholds: operators can adjust required approvals per pending command with audit events recorded.
- Bulk operator actions: command rows now support multi-select + bulk approve/reject for faster queue handling.
- Bulk payload guardrails: duplicate command ids are rejected and partial-failure details are returned to operators.
- Ticket handoff validation: remediation ticket creation now enforces stricter project key and summary/description shape checks before action queueing.
Skill Pack Install Guardrails
Skill Pack install now runs through Trust Fabric policy enforcement first, and optionally runs gateway scanning when enabled.
POST /api/v1/skill-packs/{id}/install
{
"installed_by": "platform_admin",
"scan_path": "backend/app/claws/identityclaw"
}
- Policy deny blocks install with
403. - Gateway high risk blocks install with
400. - Successful installs include
install_policyand optionalgateway_scanmetadata. - Lifecycle UI: the Skill Packs page now exposes update preview, upgrade, rollback availability, and rollback execution for installed packs.
Swarm + E2E Messaging Flag Path
Swarm task execution now emits secure inter-Node handoff metadata when AGT_ENABLE_E2E_MESSAGING=true.
- Task output includes a
secure_channelenvelope and digest. policy_decisionsincludesE2E_MESSAGEoutcome metadata.- When AGT is unavailable, the path remains deterministic with simulated encrypted envelope status.
Sprint 6 Operator Flow
- Preset endpoint:
POST /api/v1/swarm/jobs/presets/suspicious-identitylaunches Identity/Threat/Cloud/Data/Compliance/Automation participants with incident-response defaults. - Live investigation artifacts: Swarm detail shows ticket draft text and compliance impact rollup from task/judge evidence.
- Direct ticket handoff:
Create Ticketposts a governed action spec toPOST /api/v1/remediation/triggerwith draft content and compliance context.
Ticket Handoff Validation
Swarm ticket handoff uses the existing remediation trigger route and validates required ticket parameters before the remediation engine queues or executes the action.
POST /api/v1/remediation/trigger { "triggered_by": "swarm:<job_id>", "action_spec": { "provider": "generic", "action_type": "create_jira_ticket", "target_type": "ticket", "target_id": "<swarm_job_id>", "parameters": { "project_key": "SEC", "summary": "[Enkstein] Incident title", "description": "Generated ticket draft", "compliance_impact": [] } } }
E2E Coverage
The frontend includes a Playwright test for Swarm Create Ticket flow:
cd frontend npm run test:e2e -- e2e/swarm-create-ticket.spec.ts
The Playwright config starts Next.js on 127.0.0.1:3100. Environments that block local port binding need to run this test on a normal developer host or CI runner.
Operational Regression Fixes (Shipped)
- Policy pack stats route route ordering fixed so
GET /api/v1/policy-packs/statsis no longer shadowed by dynamic pack-id routes. - Schedule delete path now clears linked run references first, preventing FK failures when deleting schedules with existing run history.
- Autonomy emergency mode activate/deactivate endpoints now accept object JSON payloads from UI clients.
- Run replay alias added:
GET /api/v1/orchestrations/run-replay/{run_id}. - Capability Node contract compatibility ensured for AI Security and Identity Security findings/providers routes.
26 Capability Nodes
Each security Capability Node is a self-contained domain module with standardized endpoints, provider adapters, findings, and focused task execution. Model Cortex, Command, and Release Governance are documented separately as core control surfaces.
| Capability Node | Domain | Key Providers |
|---|---|---|
| 🤖 AI Security | AI & LLM Security | Microsoft AGT, OpenAI, Anthropic |
| 🪪 Identity Security | Identity Governance & NHI | Entra ID, Okta, AWS IAM |
| ☁️ Cloud Security | Cloud Security Posture | AWS, Azure, GCP |
| 🌐 Exposure Management | External Attack Surface | Shodan, Censys, custom |
| 🛡️ Endpoint Security | Endpoint Detection & Response | CrowdStrike, SentinelOne, Defender |
| 🔍 Threat Analysis | Threat Intelligence | VirusTotal, MISP, custom feeds |
| 📋 Security Telemetry | Log Management & SIEM | Splunk, Elastic, Sentinel |
| 🌐 Network Security | Network Security | Palo Alto, Fortinet, Cisco |
| 🔑 Privileged Access | Access Control & IAM | Okta, Entra ID, AWS IAM |
| 🗂️ Data Security | Data Loss Prevention | Purview, Nightfall, Symantec DLP |
| 📱 Application Security | Application Security | Snyk, Semgrep, Checkmarx |
| ☁️ SaaS Security | SaaS Security Posture | Obsidian, AppOmni, custom |
| ⚙️ Configuration Security | Configuration Compliance | AWS Config, Azure Policy, Chef InSpec |
| 🧱 Terraform Governance | Terraform & IaC Security Governance | Terraform Cloud, tfsec/Trivy, Checkov, Infracost |
| ✅ Compliance Assurance | Compliance Frameworks | Drata, Vanta, custom |
| 🔒 Privacy Governance | Privacy & GDPR | OneTrust, custom |
| 🏢 Vendor Risk | Third-Party Risk | BitSight, SecurityScorecard |
| 👤 User Risk | User Behavior Analytics | Varonis, Securonix |
| 🔎 Insider Risk | Insider Threat | Teramind, custom |
| ⚡ Security Automation | Automation Security | Custom, GitHub Actions |
| 🗺️ Attack Path Analysis | Attack Path Analysis | BloodHound, Orca, custom |
| 💻 Developer Security | DevSecOps & CI/CD | Snyk, Trivy, GitHub Advanced Security |
| 🧠 Threat Intelligence | Threat Intel Feeds | STIX/TAXII, custom OSINT |
| 🔄 Recovery Readiness | Incident Recovery | PagerDuty, custom runbooks |
| 🔌 Custom Capability | Custom REST Integrations | Any REST API |
The Capability Node Pattern
Capability Nodes share conventions for findings, providers, scans, and focused tasks, while their exact routes reflect the evidence and actions of each domain. OpenAPI remains authoritative.
Directory Structure
backend/app/claws/ └── cloudclaw/ ├── __init__.py ├── routes.py # FastAPI router + business logic ├── models.py # SQLAlchemy models ├── schemas.py # Pydantic request/response schemas └── providers/ ├── aws.py ├── azure.py └── gcp.py
Common Endpoint Patterns
Common routes under /api/v1/{clawname}/ include:
Routes File Template
from fastapi import APIRouter, Depends from app.trust_fabric import require_authorization CLAW_NAME = "cloudclaw" PROVIDER_MAP = {"aws": aws_provider, "azure": azure_provider} router = APIRouter(prefix=f"/api/v1/{CLAW_NAME}", tags=[CLAW_NAME]) @router.get("/stats") async def get_stats(): ... @router.get("/findings") async def get_findings(): ... @router.get("/providers") async def get_providers(): ... @router.post("/scan", dependencies=[Depends(require_authorization)]) async def run_scan(): ... @router.post("/task", dependencies=[Depends(require_authorization)]) async def run_task(): ...
Provider Adapters
Each Capability Node connects to external security tools and cloud services via provider adapters. Adapters normalize provider-specific responses into Enkstein's standard findings schema.
Adapter Interface
All adapters implement a consistent interface:
class BaseProvider: async def authenticate(self) -> bool: ... async def get_findings(self, **kwargs) -> list[Finding]: ... async def run_scan(self, config: ScanConfig) -> ScanResult: ... async def health_check(self) -> ProviderStatus: ...
Finding Schema
All providers return findings normalized to:
{
"id": "uuid",
"claw": "cloudclaw",
"provider": "aws",
"severity": "HIGH", // CRITICAL | HIGH | MEDIUM | LOW | INFO
"title": "S3 bucket publicly accessible",
"description": "...",
"resource_id": "arn:aws:s3:::my-bucket",
"resource_type": "S3Bucket",
"remediation": "Block public access...",
"compliance_tags": ["SOC2-CC6", "CIS-2.1"],
"first_seen": "2025-01-15T10:30:00Z",
"last_seen": "2025-01-20T08:00:00Z",
"status": "OPEN" // OPEN | ACKNOWLEDGED | RESOLVED | SUPPRESSED
}
Connector Configuration
Provider credentials are stored as connectors in the database (never in code). The seed_connectors.py script creates example connectors. Manage connectors via:
GET /api/v1/connectors/ POST /api/v1/connectors/ PATCH /api/v1/connectors/{id} DELETE /api/v1/connectors/{connector_id}/credentials
Connector cards use curated brand icons (local assets first, CDN fallback second). Key normalization, alias resolution, and keyword fallback prevent broken logos when connector types vary slightly across providers.
Latest connector UI updates include curated local brand assets for major providers (identity, SIEM, endpoint, cloud, and network connectors) plus white-background rendering for logo families that require it.
Agents & Workflows
CoreOS is Enkstein's orchestration layer. Agents are autonomous execution units; workflows chain agent actions into governed multi-step processes.
Agents
An agent is a named, persistent execution context with:
- Identity — every agent has its own principal for Trust Fabric evaluation
- Skill packs — curated sets of allowed actions the agent can perform
- Memory — persistent key-value context carried between executions
- Execution mode — agents inherit or override the Capability Node's execution mode
- Profile — behavioral baseline profile used by anomaly detection
Agents are seeded via seed_agents.py and managed at /api/v1/agents/.
Workflows
Workflows are directed acyclic graphs (DAGs) of agent steps. Each step specifies:
- Which agent executes it
- What action to perform (from the agent's skill pack)
- Input/output data mappings between steps
- Conditional branching based on step outcomes
- Retry policy and timeout configuration
Example Workflow: Incident Response
{
"name": "Cloud Incident Response",
"steps": [
{ "id": "1", "agent": "detection-agent", "action": "collect_findings" },
{ "id": "2", "agent": "triage-agent", "action": "risk_score", "depends_on": ["1"] },
{ "id": "3", "agent": "contain-agent", "action": "isolate_resource",
"depends_on": ["2"], "mode": "APPROVAL" }
]
}
Event Triggers
Event triggers allow Enkstein to react automatically to security events — findings crossing severity thresholds, policy violations, external webhook payloads, and schedule-based cadences.
Test Trigger actions from the frontend, calling POST /api/v1/triggers/{id}/test with sample payloads and returning immediate match/non-match feedback.
Trigger Types
| Type | Description | Example |
|---|---|---|
FINDING | New finding matches criteria | New CRITICAL finding in Cloud Security |
THRESHOLD | Metric crosses a threshold | Risk score > 80 for any actor |
POLICY_VIOLATION | Policy DENY decision recorded | Any DENY in AUTONOMOUS mode |
WEBHOOK | External HTTP event received | GitHub push to main branch |
SCHEDULE | Cron-based recurring trigger | Daily cloud posture scan at 02:00 |
MANUAL | Operator-initiated | Incident response initiation |
Trigger Configuration
POST /api/v1/triggers/ { "name": "Critical finding response", "type": "FINDING", "conditions": { "severity": "CRITICAL", "status": "OPEN" }, "action": { "type": "START_WORKFLOW", "workflow_id": "incident-response-v2" } }
Scheduling
CoreOS includes a cron-based scheduling engine for recurring security scans, compliance checks, and report generation.
Creating a Schedule
POST /api/v1/schedules/ { "name": "Nightly cloud posture scan", "cron": "0 2 * * *", "timezone": "UTC", "action": { "type": "CLAW_SCAN", "claw": "cloudclaw", "provider": "aws" }, "enabled": true }
Seeded Schedules
The seed_triggers.py script creates a default schedule set:
- Nightly cloud posture scan (02:00 UTC)
- Hourly identity governance sweep
- Weekly compliance report generation
- Daily anomaly baseline refresh
Terraform Governance
Terraform Governance is the Terraform and infrastructure-as-code governance Capability Node. It builds secure Terraform from plain English, reviews HCL, generates secure templates, analyzes Terraform plan risk before apply, and participates in Swarm investigations through the standard task contract.
What Terraform Governance Covers
- Natural-language generation:
POST /api/v1/terraclaw/generatereturns governed Terraform output with review evidence and applied controls. - HCL review: local rule checks for public network exposure, weak data protection, excessive IAM permissions, hardcoded secrets, missing diagnostics, and risky Kubernetes control plane settings.
- Agentic secure generation: approved Terraform templates for common cloud patterns with private networking, encryption, diagnostic logging, and secret-management defaults. The Generate surface now behaves like a Terraform Governance agent session with Terraform MCP trace, module artifacts, applied controls, and handoffs into Review and Plan Analysis.
- Plan analysis: pre-apply review of creates, updates, deletes, replacements, and sensitive attribute changes with APPROVE / WARN / BLOCK decisions.
- Compliance mapping: findings map to CIS AWS, CIS Azure, NIST, SOC 2, ISO 27001, PCI-DSS, and OWASP sensitive-data controls where applicable.
Provider Surfaces
Terraform Governance exposes provider status for Terraform MCP, Terraform Cloud, tfsec/Trivy, Checkov, and Infracost. Current runtime behavior includes deterministic rule review, secure Terraform generation, MCP-callable tools through the Enkstein MCP server, seeded fallback findings, scan persistence, connector-state metadata, and Swarm task output; deeper live provider-backed ingestion remains an adapter expansion area.
Core Endpoints
Release Governance
Release Governance is the Zero Trust deployment governance surface. It normalizes CI/CD, GitOps, cloud SDK/CLI, scripting, full-stack, and AI-stack deployments into one preflight, approval, handoff, and evidence contract.
Supported Deployment Paths
Release Governance supports deployment requests from GitHub Actions, GitLab CI, Jenkins, Azure DevOps, ArgoCD, Terraform Cloud, AWS CLI/SDK, Azure CLI/SDK, GCloud, Kubernetes, Helm, Docker, Docker Compose, Bash, PowerShell, Python, Node, Ansible, webhooks, and custom adapters.
Deployment Flow
- Normalize request — source, environment, application, change reference, deployment type, mode, artifacts, execution plan, and rollback plan.
- Apply template controls — required controls and Capability Node coverage are selected from release templates such as GitHub Actions production, Terraform apply, ArgoCD sync, full-stack app, AI service stack, or emergency patch.
- Score blockers — missing rollback plans, unsafe script content, missing model profile for AI-stack deployments, production mode, and sensitive classification increase risk.
- Trust Fabric decision — deployment preflight, approval, and execute handoff are audited and policy-governed.
- Evidence bundle — result includes controls, Capability Nodes, policy decision, artifacts, handoff metadata, and a SHA-256 chain-of-custody hash.
Core Endpoints
Example Preflight
{
"requested_by": "release-owner",
"source": "github_actions",
"environment": "prod",
"application": "customer-api",
"change_ref": "release-2026.06.02",
"deployment_type": "container",
"mode": "APPROVAL_REQUIRED",
"template_id": "github-actions-prod",
"execution_plan": [{ "step": 1, "command": "workflow_dispatch customer-api production" }],
"rollback_plan": [{ "step": 1, "command": "restore previous artifact" }]
}
Approval Flows
When the Trust Fabric returns an ESCALATE decision — or when a Node step is configured with APPROVAL execution mode — the action enters an approval queue requiring explicit human sign-off.
Approval Tiers
| Tier | Risk Score | Approvers | Timeout |
|---|---|---|---|
| T1 — Standard | 40–59 | Any security team member | 24 hours |
| T2 — Elevated | 60–79 | Security team lead | 4 hours |
| T3 — Critical | 80+ | CISO or designated approver | 1 hour |
Approval APIs
Approvals are owned by the workflow that created them; there is no global queue that can approve unrelated action types through one generic endpoint.
Execution Ring Policy
Every governed action is classified into one of four privilege rings. The ring determines whether the action is auto-allowed, requires approval, or is blocked outright with a deterministic execution_ring_violation deny reason.
| Ring | Scope | Rule |
|---|---|---|
| ring0 | System / kernel | Hard-blocked — no role, trust score, or approval can bypass |
| ring1 | Privileged (quarantine, suspend, IAM, delete secret) | 2 approvals required; low-privilege roles denied |
| ring2 | Standard (tickets, alerts, kill process) | Auto-allow at trust ≥ 80, else 1 approval |
| ring3 | Unprivileged (read logs, lookup CVE, list) | Always auto-allowed |
Implemented in backend/app/services/ring_policy.py; enforced in exec channels and the remediation approval path. 32 tests in test_ring_policy.py.
Governed Execution Channels
Shell, browser, and credential execution requests pass through the Trust Fabric before running. Shell/browser/credential channels require dual approval, self-approval is blocked (the requester cannot approve their own request), and the approver identity is always taken from the JWT — never the client body.
Connector & Skill-Pack Provenance
Skill pack installs are verified at install time via SHA-256 content hash and optional Ed25519 publisher signature. A tampered manifest fails the integrity check and the install is blocked with manifest_integrity_failure. Unsigned community packs are allowed with a warning.
Implemented in backend/app/services/provenance.py; 10 tests in test_provenance.py.
Cloud Provider Integrations
Cloud Security and related modules integrate with all major cloud providers for posture management, identity, and logging.
AWS
Authentication via IAM Role (recommended) or access key. Required permissions depend on enabled capability nodes:
SecurityHub:GetFindings— Cloud Security posture findingsIAMAccessAnalyzer:ListFindings— Identity Security NHI analysisCloudTrail:LookupEvents— Security Telemetry audit ingestionConfig:DescribeConfigRules— Configuration Security compliance
# .env AWS_ACCESS_KEY_ID=your-key AWS_SECRET_ACCESS_KEY=your-secret AWS_DEFAULT_REGION=us-east-1
Azure
Authentication via Service Principal with Client Secret or Managed Identity:
AZURE_TENANT_ID=your-tenant AZURE_CLIENT_ID=your-client-id AZURE_CLIENT_SECRET=your-secret
Google Cloud
Authentication via service account JSON or Application Default Credentials:
GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json GCP_PROJECT_ID=your-project
Endpoint Security Integrations
Endpoint Security integrates with leading EDR platforms to pull findings and initiate containment actions.
Supported Providers
| Provider | Capabilities | Auth Method |
|---|---|---|
| CrowdStrike Falcon | Detections, device management, RTR containment | OAuth2 client credentials |
| SentinelOne | Threats, agents, network isolation | API token |
| Microsoft Defender | Alerts, devices, investigation packages | Entra ID app registration |
| Elastic Defend | Alerts, endpoint actions | API key |
SIEM & Log Management
Security Telemetry centralizes security telemetry from external SIEM and log management platforms into the Enkstein findings pipeline.
Supported Platforms
- Splunk — REST API with saved search queries; alerts forwarded via webhook
- Elastic Security — ES|QL queries via Elasticsearch API
- Microsoft Sentinel — Log Analytics REST API with KQL queries
- Sumo Logic — Search job API
- Custom syslog — CEF/LEEF ingest via the channel gateway
Log Normalization
Ingested logs are normalized to the Enkstein finding schema using field-mapping rules stored in the database. The seed_channel_gateway.py and seed_exec_channels.py scripts configure the ingest channels.
Identity Provider Integrations
Identity Security and Privileged Access integrate with identity providers for user governance, privileged access management, and non-human identity discovery.
Supported Providers
| Provider | Capabilities |
|---|---|
| Microsoft Entra ID (Azure AD) | User sync, guest accounts, app registrations, NHI discovery, PIM alerts |
| Okta | User lifecycle, MFA status, suspicious activity alerts, service accounts |
| AWS IAM | User keys, roles, unused permissions, IAM Access Analyzer |
| Google Workspace | User accounts, OAuth grants, admin alerts |
Non-Human Identity (NHI)
Identity Security's NHI module discovers and governs service accounts, API keys, OAuth tokens, and machine credentials. NHIs are tracked with:
- Owner attribution
- Last-used timestamps
- Permission scope analysis
- Expiry and rotation status
- Risk score based on permissions × staleness
Authentication
Enkstein uses bearer tokens for authenticated API calls. The desktop owner flow requires a local username, password, and TOTP code.
Obtaining a Token
POST /api/v1/auth/owner/login Content-Type: application/json { "username": "local-owner", "password": "your-owner-password", "code": "123456" }
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 900
}
Using the Token
Include the access token in all subsequent requests:
GET /api/v1/cloudclaw/findings
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Token Claims
The local owner token includes:
sub— local owner usernamerole— owner role (admin)mfa_verifiedandauth_method— authentication assurance contextexp— expiry timestamp
Governed routes use the authenticated subject as actor context when evaluating policy and writing audit records.
Endpoints Overview
All endpoints are under /api/v1/. The interactive Swagger UI is available at http://localhost:8000/docs when running locally.
Auth
Trust Fabric
Policies
Capability Nodes
Node routes vary by domain. Common suffixes include /stats, /findings, /providers, /scan, and /task; use the generated OpenAPI page for the exact installed surface.
CoreOS
Findings Pipeline
When a Node scan completes, findings pass through a normalization and enrichment pipeline before being stored and surfaced to the dashboard.
Pipeline Stages
- Raw provider response — Provider adapter returns provider-specific data.
- Normalization — Adapter maps provider fields to the standard finding schema.
- Deduplication — Findings are matched against existing open findings by resource ID + title hash. Duplicates update
last_seenrather than creating new records. - Enrichment — Compliance tag mapping, asset context lookup, and risk score calculation are applied.
- Storage — Enriched findings are written to the Capability Node's findings table.
- Trigger evaluation — New CRITICAL findings and threshold crossings are evaluated against active triggers.
Finding Lifecycle
OPEN → ACKNOWLEDGED → RESOLVED
↕
SUPPRESSED (skip notifications; still logged)
Compliance Evidence Export
Compliance Assurance exposes a Trust Fabric-governed JSON evidence export for audit handoff and internal compliance review.
{
"requested_by": "compliance-admin",
"frameworks": ["SOC 2", "ISO 27001"],
"include_findings": true,
"include_audit_logs": true,
"max_audit_logs": 100,
"classification": "confidential"
}
- Exports run through Trust Fabric policy enforcement before data is returned.
- Responses include
policy_decision,summary,controls,findings,audit_logs, andchain_of_custody. - The chain-of-custody block includes a SHA-256 bundle hash for downstream evidence handling.
- Exports are vendor-generated evidence bundles; independent audit review is still required before compliance reliance.
Running Tests
Enkstein uses pytest for the backend and Jest for the frontend. A complete test run covers unit tests, integration tests, and API contract tests.
Backend Tests
cd backend pip install -r requirements-test.txt # Run all tests pytest tests/ -v --tb=short # Run a specific Capability Node's tests pytest tests/claws/test_cloudclaw.py -v # Run with coverage pytest tests/ --cov=app --cov-report=term-missing
Frontend Tests
cd frontend npm install npm run test # Jest unit tests npm run build # Type-check + production build
Test Database
Integration tests use an isolated PostgreSQL instance configured in tests/conftest.py. Fixtures create and teardown test data per test session. Set TEST_DATABASE_URL in your environment or .env.test to override the default SQLite-in-memory fallback.
CI/CD Pipeline
Enkstein uses GitHub Actions for continuous integration. The pipeline runs on every push and pull request to main.
Workflow File
Located at .github/workflows/ci.yml. The pipeline consists of four parallel jobs:
| Job | Runner | Steps |
|---|---|---|
test-backend | ubuntu-latest | Python setup → pip install → pytest with PostgreSQL service |
lint-backend | ubuntu-latest | Python setup → ruff check → ruff format --check |
test-frontend | ubuntu-latest | Node 20 setup → npm ci → npm run build → Jest |
docker-build | ubuntu-latest | Docker Buildx → build backend + frontend images (no push on PRs) |
Branch Protection
All four CI jobs must pass before merging to main. The docker-build job pushes to the container registry only on merges to main, tagged with the commit SHA and latest.
Running Locally
# Lint cd backend && ruff check . && ruff format --check . # Type check cd frontend && npx tsc --noEmit
Adding a New Capability Node
Adding a new security Capability Node takes 5 steps. The existing capability nodes in /backend/app/claws/ are the best reference implementations.
-
Create the claw directory
mkdir -p backend/app/claws/newclaw/providers touch backend/app/claws/newclaw/__init__.py touch backend/app/claws/newclaw/routes.py touch backend/app/claws/newclaw/models.py touch backend/app/claws/newclaw/schemas.py
-
Implement
routes.pyDefineCLAW_NAME,PROVIDER_MAP, and the four standard endpoints (get_stats,get_findings,get_providers,run_scan). All mutating operations must useDepends(require_authorization)so they route through the Trust Fabric. -
Create SQLAlchemy models Define a findings table model inheriting from
BaseModel. Add an Alembic migration:alembic revision --autogenerate -m "add newclaw findings table" alembic upgrade head
-
Register the router in
main.pyfrom app.claws.newclaw.routes import router as newclaw_router app.include_router(newclaw_router)
-
Add the frontend page Create
/frontend/src/app/newclaw/page.tsxfollowing the pattern of an existing claw page. Register the claw in the sidebar navigation component. The page should fetch from/api/v1/newclaw/statsand/api/v1/newclaw/findings.
cloudclaw as a starting point — it has the most complete implementation including provider stubs, full Pydantic schemas, and a working frontend page.
Alembic Migrations
Database schema changes are managed with Alembic. All migrations live in backend/alembic/versions/.
Common Commands
cd backend # Create a new autogenerated migration alembic revision --autogenerate -m "describe your change" # Apply all pending migrations alembic upgrade head # Rollback one migration alembic downgrade -1 # View current migration state alembic current # View migration history alembic history --verbose
Migration Guidelines
- Always review autogenerated migrations before applying — Alembic may miss complex changes.
- Never modify existing migration files after they have been applied in any environment.
- Include both
upgrade()anddowngrade()functions in every migration. - For large table changes, add
batch_alter_tablesupport for SQLite compatibility in tests. - Data migrations (seeding, backfills) go in separate migration files, not in seed scripts.
alembic upgrade head in production. Long-running migrations on large tables should use CONCURRENTLY index builds or batched updates.
