FAQ

Frequently asked questions

Everything you need to know about expacti. Can't find an answer? Email us.

How it works
What exactly is expacti?

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.

Does the agent have to be modified to use expacti?

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.

Do I have to approve every single command?

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.

What happens if I'm not available to approve a command?

You configure a timeout policy per org. Options:

  • Auto-deny (recommended): if no reviewer responds within N seconds, the command is denied. Safe default.
  • Escalate: alert a backup reviewer (configured per org).
  • Auto-approve: not recommended for most cases, but available for low-risk workflows where availability is critical.

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.

How does the whitelist work in practice?

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.

What does "session recording" mean?

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.

Latency & performance
How much latency does expacti add?

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.

Isn't this too slow for automated pipelines?

It depends on what "too slow" means for your use case. Some perspectives:

  • A deploy pipeline that takes 8 minutes and adds 10 seconds of human approval latency is still much faster than doing the deploy manually.
  • Most automation is not actually time-critical at the individual-command level. A CI job that runs for 15 minutes can afford a 30-second approval window.
  • For genuinely latency-sensitive automated work, you build up the whitelist first. After the first few runs, almost nothing requires approval.

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.

What's the proxy overhead for SSH connections?

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.

Security
Does expacti see my commands in plaintext?

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.

What if the expacti proxy is compromised?

The threat model accounts for this. Key mitigations:

  • The proxy is stateless — the whitelist and approval state live in the database, not in the proxy process.
  • The audit log is append-only with a hash chain. A compromised proxy can't retroactively alter history.
  • Each approval has a unique short-lived token (30-second TTL). Replay attacks are prevented even if the proxy is observed.
  • With E2E encryption, a compromised proxy can't read commands — only relay encrypted blobs.
  • For self-hosted deployments, the proxy runs in your own infrastructure and network.

Full threat model: expacti.com/security.

How does reviewer authentication work?

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.

Can a reviewer approve their own commands?

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.

Is there anomaly detection?

Yes. Eight built-in anomaly rules fire automatically:

  • Commands outside normal operating hours for this agent
  • Commands from an unusual source IP
  • Unusual target server for this agent identity
  • High-frequency command submission (potential loop or runaway agent)
  • Pattern deviation from historical baseline for this agent
  • First-time use of a high-risk command class
  • Multiple consecutive denials in a session
  • Approval requested within seconds of a previous denial (retry storm)

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.

Integration
Which AI agent frameworks does expacti support?

Anything that supports tool/function calling. Native integrations:

  • Python: LangChain (ShellTool drop-in), LangGraph, any custom agent with function calling
  • TypeScript: Vercel AI SDK (with Zod schema), LangChain.js, OpenAI function calling
  • Go: expacti-go with Shell helper for any Go agent
  • Rust: expacti-sdk (tokio-tungstenite)
  • Java/Kotlin: expacti-java with LangChain4j tool
  • Ruby, PHP, .NET: SDKs available in the repo

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.

How do I integrate with Slack?

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).

Does expacti work with GitHub Actions?

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.

Can I use expacti as a bastion/jump host?

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.

Is there a REST API?

Yes. Full REST API documented in OpenAPI 3.0 format (docs/openapi.yml). Endpoints for:

  • Auth (login, signup, TOTP, OIDC)
  • Org management (targets, members, invites, notifications)
  • Whitelist CRUD (add, update, delete, import, export)
  • Commands (approve, deny, list, audit log)
  • Sessions (list, recordings, analytics)
  • AI suggestions (list, accept, dismiss)
  • Compliance reports (SOC2, ISO27001, summary)

API keys are available (format: expacti_<32hex>) for programmatic access without JWT sessions.

Pricing
Is there a free tier?

Yes. The free tier includes:

  • 1 target server
  • 1 reviewer
  • 100 commands per month
  • 30 days of history
  • All core features (whitelist, approval flow, audit log, session recording)

No credit card required to start. The free tier is generous enough to protect your most critical single server while you evaluate.

What does Pro include?

Pro ($29/month) includes:

  • 10 target servers
  • 5 reviewers
  • Unlimited commands
  • 1 year of history
  • Compliance report exports
  • Slack + Teams integration
  • PWA mobile reviewer
  • AI whitelist suggestions
  • Priority support
What about Enterprise pricing?

Enterprise pricing is custom and includes:

  • Unlimited targets and reviewers
  • SAML 2.0 SSO + SCIM provisioning
  • Self-hosted option (Docker Compose or Kubernetes)
  • E2E encryption
  • Custom data retention
  • SLA with dedicated support
  • Terraform provider + K8s operator
  • Multi-party approval policies

Contact us at [email protected].

Can I self-host instead of using the cloud service?

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).

Self-hosting
What are the minimum server requirements?

For a small team (under 10 reviewers, under 5 targets):

  • 1 vCPU, 512MB RAM, 10GB disk
  • Docker and Docker Compose installed
  • Outbound HTTPS for OIDC and notification providers (optional)

The backend is a single Rust binary with minimal memory footprint. SQLite handles persistence for small deployments without any additional database setup.

How do I run the eval stack?

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.

How do updates work for self-hosted?

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.

Can I use PostgreSQL instead of SQLite?

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.

Still have questions?

Try the interactive demo to see it in action, or reach out directly — we reply to every email.