Everything you need to know about expacti. Can't find an answer? Email us.
expacti is a human-in-the-loop proxy that sits between an automated agent (AI coding agent, CI pipeline, deployment bot, or any script) and the systems it controls. Every command the agent tries to run is intercepted and held until a human reviewer approves or denies it.
Think of it as a code review process, but for actions instead of code — and in real time.
Minimal modification. We provide SDKs for Python, TypeScript/Node, Go, Rust, Java/Kotlin, Ruby, PHP, and .NET — each with a drop-in tool wrapper. In most frameworks (LangChain, Vercel AI SDK, LangGraph), it's a one-line swap:
ExpactiTool(client=client) instead of ShellTool()
For CI/CD pipelines (GitHub Actions, etc.), there's a composite action that wraps any shell step. For direct SSH access, expacti-sshd acts as a transparent SSH proxy — no agent modification needed at all.
No — that would make it unusable. The whitelist is the key mechanism. The first time you see a command (docker ps, git pull, etc.), you approve it and it gets added to the whitelist. Future runs of the same command execute automatically.
After a few agent runs, the whitelist covers the routine work. You only see commands that are genuinely new, unexpected, or high-risk. In practice, a mature deploy agent might run for days without triggering a single manual approval.
You can also configure TTL-based expiry, so temporary permissions don't accumulate silently.
You configure a timeout policy per org. Options:
The default is auto-deny at 60 seconds with a push notification to all configured reviewers. You can set this from 30 seconds to 10 minutes.
Each whitelist entry has a pattern type: exact match, glob, or regex. Exact match is the default and safest. When you approve docker ps, that exact string is whitelisted — nothing else.
For patterns with variable parts (e.g. docker logs <container-id>), you can manually upgrade the rule to a glob or regex after reviewing it. The AI suggestions engine also proposes these upgrades automatically based on observed patterns.
Rules are scoped: global (any target), target group, or specific target. A rule on prod-server doesn't apply to staging-server.
Every agent session is recorded in asciinema format: full PTY output with timestamps, per character. You can replay any session in the browser at any speed, jump to a specific command, and see exactly what the agent saw.
This is essential for incident forensics. "What did the agent actually do at 3am on March 25th?" — you can answer that question precisely.
For whitelisted commands: under 5ms added overhead. The whitelist check is an in-memory lookup.
For commands requiring human review: the latency is the time a human takes to respond. In our experience, familiar commands take 5–15 seconds. Novel or high-risk commands take 30–90 seconds.
The right mental model: expacti adds near-zero latency to routine automation, and human-scale latency only to actions that genuinely need a human. That's a feature, not a bug.
It depends on what "too slow" means for your use case. Some perspectives:
The one case where expacti doesn't fit: fully automated, latency-critical pipelines that can't tolerate any human-in-the-loop step. For everything else, the overhead is acceptable.
The expacti-sshd proxy is implemented in Rust with async I/O (tokio). Round-trip overhead for the proxy itself is typically under 2ms on LAN, under 10ms on a well-connected VPS.
The proxy adds no overhead to PTY passthrough (interactive keystrokes, output streaming). Overhead only occurs at the command boundary — when Enter is pressed and the command needs to be evaluated.
Not if you enable end-to-end encryption. expacti supports zero-knowledge command relay using RSA-OAEP + AES-256-GCM hybrid encryption. The agent encrypts the command with the reviewer's public key; the backend relays the ciphertext without decrypting it; only the reviewer's browser can read the command.
In E2E mode, even if someone gained access to the expacti backend, they would only see encrypted blobs.
E2E encryption is optional (some teams prefer searchable audit logs over zero-knowledge). The reviewer dashboard shows a 🔒 badge on encrypted commands.
The threat model accounts for this. Key mitigations:
Full threat model: expacti.com/security.
Reviewers authenticate with email + password + TOTP (2FA). TOTP is enforced — there's no way to skip it once enabled for your org. Backup codes are provided at enrollment (bcrypt-hashed, single-use).
For enterprise: SAML 2.0 SSO (Okta, Azure AD, Google Workspace) means reviewers use their existing corporate identity. SCIM provisioning keeps user lists in sync with your IdP automatically.
Reviewer sessions are short-lived JWTs. Revocation takes effect at the next API call.
By default, no. The agent identity and reviewer identity are separate roles. An admin can configure multi-party approval policies that require approvers with a specific role, or a minimum number of independent reviewers.
For high-security environments, configure require_n_approvers: 2 with policy: AllOf so no single person can approve a destructive operation.
Yes. Eight built-in anomaly rules fire automatically:
Anomaly events are logged, shown with badges in the reviewer UI, and trigger notifications. They're included in compliance reports as evidence of active monitoring.
Anything that supports tool/function calling. Native integrations:
Any framework that can make a WebSocket call can integrate with the raw protocol — it's a simple JSON wire format documented in docs/ARCHITECTURE.md.
Configure your Slack bot token and signing secret in the reviewer dashboard (Notifications tab → Slack). When a command arrives for review, expacti posts a Block Kit message to your configured channel with ✅ Approve and ❌ Deny buttons.
Clicking either button resolves the approval from Slack directly — you don't need to open the dashboard. HMAC-SHA256 signature verification prevents spoofed approval requests.
Microsoft Teams is also supported via webhook (Adaptive Card format with a "Review in expacti" action button).
Yes. expacti/expacti-action is a composite GitHub Action that wraps any shell step:
uses: expacti/expacti-action@v1 with command, backend_url, shell_token, and timeout inputs.
The step blocks until a reviewer approves or denies. On deny, the step fails and the pipeline stops. On timeout (configurable), the step also fails — no silent auto-approvals.
Yes — that's what expacti-sshd is for. It's a full SSH proxy that sits between the client and the target server. Configure it as a jump host in your SSH config:
ProxyJump expacti-bastion
Every command typed in the SSH session is intercepted at the PTY level before being forwarded to the target. The reviewer sees a live terminal view and can approve/deny each command as it arrives.
Arrow keys, Tab completion, signals (Ctrl+C/D/Z), and interactive apps (vim, htop) all work correctly — only actual shell commands are intercepted.
Yes. Full REST API documented in OpenAPI 3.0 format (docs/openapi.yml). Endpoints for:
API keys are available (format: expacti_<32hex>) for programmatic access without JWT sessions.
Yes. The free tier includes:
No credit card required to start. The free tier is generous enough to protect your most critical single server while you evaluate.
Pro ($29/month) includes:
Enterprise pricing is custom and includes:
Contact us at [email protected].
Yes — self-hosting is a first-class option. The backend is open-source (Rust/Axum) and ships as a Docker image on GHCR. A zero-config eval stack is available:
make eval — spins up a full demo stack with Docker Compose, pre-configured demo tokens. No config files to edit.
Production self-hosted deployment uses Docker Compose or the Kubernetes Helm chart. Supported databases: SQLite (single-node) or PostgreSQL (production scale).
For a small team (under 10 reviewers, under 5 targets):
The backend is a single Rust binary with minimal memory footprint. SQLite handles persistence for small deployments without any additional database setup.
Three commands:
git clone https://github.com/kwha/expacti.com
cd expacti.com
make eval
This starts the backend (port 3001), Caddy reverse proxy (ports 80/443), and pre-configures demo shell and reviewer tokens. Open http://localhost/app and use the demo-reviewer-token to sign in.
make eval-down tears everything down.
Pull the latest image and restart:
docker compose pull && docker compose up -d
Database migrations run automatically on startup. No manual schema changes needed. The image is published to GHCR (ghcr.io/kwha/expacti-backend:latest) on every CI run.
Yes. Set database_url = "postgres://user:pass@host/dbname" in config.toml. The backend uses a DbPool abstraction that supports both SQLite and PostgreSQL transparently.
For production deployments with multiple reviewers and high command volume, PostgreSQL is recommended. Managed services (Supabase, Neon, RDS) all work.
Try the interactive demo to see it in action, or reach out directly — we reply to every email.