Venya and NVIDIA OpenShell
Two answers to the same question, compared on what each one enforces
OpenShell is NVIDIA's runtime for agent fleets. Venya is a secrets and execution
broker for humans and AI agents. Both confine what an agent can reach, and both
keep credentials away from the model. Neither one is a finished story, and this
page says plainly where each falls short.
Every Venya row cites a file in the tree we ship at release tag
v0.1.0beta2 (f20b365), so the comparison is something you can check rather than
something you have to take on faith.
What this page is. A technical side-by-side, written from OpenShell's published README and Venya's published documentation and source. What it is not. An attestation, an audit opinion, or a benchmark. Venya is in beta and not yet certified for regulated environments. Security claims here describe design properties of the software, not formal attestations - and where a control has a scope limit, that limit is in the same row as the control.
The first comparison: a human being, with a key
Before any capability list, the difference that changes who is accountable when something goes wrong. Venya binds a hardware security key to the human, per session and per elevation. No such mechanism appears in OpenShell's published design - their README does not mention FIDO2, WebAuthn, hardware keys, passkeys, authenticators, or multi-factor authentication at all, and the one time the word "human" appears in it, it is in the phrase "wait for human review" of a policy change (their README, line 26). We state it that way on purpose: a README is not a product boundary, so this is a statement about what they publish, not a claim about what their software cannot do. If their documentation carries a key-bound human ceremony we have missed, we will correct this section - the check is one line:
grep -inE 'fido|webauthn|hardware key|passkey|authenticator|multi-factor|2fa|mfa' openshell-readme.md # measured result against the copy this page was written from: zero matches
| What a Venya session requires | What it costs an attacker | Check it |
|---|---|---|
| A physical key touch to mint a session. The server verifies the WebAuthn/FIDO2 assertion itself; there is no password pathway for humans anywhere in the product. | A stolen token is not a session. To run anything, an attacker needs the person's registered authenticator and its PIN. | docs/controls.md §Human authorization; packages/server/src/server/fido2/manager.py::finish_authentication; docs/faq.md "Can I use passwords or TOTP?" |
| A second ceremony to read a secret value. Unmasking needs a single-use elevation token produced by a fresh key touch, and a denied attempt does not consume the token. | Reading a credential is a deliberate, separately authorized, separately audited act - not a side effect of having access. | docs/auditor-role.md "denied attempt never burns the token"; packages/core/src/core/iam/models.py::ElevationToken |
| An authorization that expires on a clock nobody can extend. 15-minute idle window, 4-hour hard cap, 5-minute access tokens. | "an agent cannot renew a human's authorization" is a shipped property, not a policy aspiration. | docs/architecture.md §Authentication and sessions; docs/faq.md "Why do sessions expire so aggressively?" |
| Offboarding removes the access, not just the account. Removing a user revokes their WebAuthn credentials, their outstanding elevation tokens, their sessions and their enrollment tokens in one operation - and the route refuses to delete the caller or the last remaining admin. | Access does not outlive the person. A stale account cannot keep authorizing work through a credential nobody remembers issuing. | packages/server/src/server/routes/admin.py::admin_remove (removal of WebAuthnCredential, ElevationToken, Session and EnrollmentToken together; the #443 lockout guards answer before anything is deleted) |
| Every command traces to the person whose key opened the session. Actor, command string, executor id, secret ids (never values), timestamps. | Attribution survives the agent. When something goes wrong you can say which human authorized the session that did it. | docs/architecture.md §Secret lifecycle step 5; docs/controls.md §Audit recording |
OpenShell's published control model is different, and it is a legitimate design: policy is enforced by the kernel and by a network gate, and risky policy changes wait for human review after formal verification flags them (their README, lines 23-26). That puts the human on the configuration path. Venya also puts a human on the execution path, every session, by way of a physical key. Those are different trust models, and the difference is visible the moment a credential is stolen: under Venya the theft buys nothing without the key.
Where the two products sit
The honest starting point is that these are not the same object. OpenShell is a runtime: you install a gateway, and agents run inside sandboxes it governs, with policy enforced at the kernel and at the network boundary. Venya is a broker: your agent's harness keeps running wherever it runs today, and the commands that need real credentials are handed to an executor daemon that runs them inside a sandbox and returns filtered output.
OpenShell
- Gateway + supervisor + per-agent sandbox
- Kernel policy on file access and syscalls
- Network checks before a connection leaves the sandbox
- Credentials added only at approved endpoints
- Formal verification flags risky policy changes
Venya
- Core (secrets, IAM, audit, CA) + executor daemon
- Commands run in a microVM sandbox
- Deny-by-default egress including DNS names
- Values injected in the sandbox, never in the model's context
- Human hardware-key authorization per session
That difference in shape decides most of what follows. OpenShell's leverage is the kernel and the prover. Venya's leverage is that a person with a security key is inside the trust path for every session and every disclosure, and that the record of what happened is enforced by the database rather than by convention.
Capability comparison
OpenShell's capabilities are quoted from its README (line numbers are given so the quote can be checked against the file). Venya's column says what the shipped code does, names the document or symbol that governs it, and states the scope limit. The last column is deliberately blunt: Shipped means the code enforces it, Partial means it enforces part of it, and Not shipped means Venya does not do this today.
| Capability | OpenShell (their words) | Venya's shipped behavior | Check it | Venya status |
|---|---|---|---|---|
| Human authorization for a session | No such mechanism appears in their published design - their README does not mention FIDO2, WebAuthn, hardware keys, passkeys or multi-factor authentication anywhere (see the section above) | A session is minted only after a WebAuthn/FIDO2 assertion is verified server-side. There is no password pathway for humans in the product at all. Sessions carry a 15-minute idle window, a 4-hour hard cap and 5-minute access tokens, so an agent cannot renew a human's authorization. | docs/controls.md §Human authorization; fido2/manager.py::finish_authentication; docs/faq.md "Can I use passwords or TOTP?" |
Shipped |
| Isolated execution per agent | "Each agent runs in an isolated sandbox" (README:25) | Commands run in Docker Sandboxes (sbx) microVMs, one ephemeral execution session per run; the target hosts themselves are untouched. |
docs/architecture.md §Sandbox and egress; docs/faq.md "Is there Docker?" |
Shipped |
| Kernel-level confinement of file access and syscalls | "Kernel controls confine which files it can access and which system calls it can make" (README:25) | Venya does not write per-agent kernel policy. The executor service runs under a seccomp profile with PrivateTmp, and the isolation boundary for a command is the microVM itself, not a syscall filter around a chosen directory set. |
docs/architecture.md §Sandbox and egress ("The executor service runs under a seccomp profile, PrivateTmp...") |
Not shipped - OpenShell is broader here |
| Per-command policy applied before execution | Filesystem, network and process rules, declared in a policy (README:46) | A deny-by-default blocklist is scanned into every command before it runs (16 named commands ship in the default list), commands must resolve into trusted directories, and shell metacharacters, pipes and redirects are refused structurally per element rather than by pattern. The blocklist is a default an administrator can replace. | docs/controls.md §Command policy and §Command resolution - each row carries a symbol and the one command that re-derives it |
Shipped, scoped |
| Scope of that command policy | Applies at the sandbox boundary | On an ssh/sshpass command only the local (sandbox) half is scanned; tokens after the destination are remote-side and pass. This is shipped design with a named test guarding it, so a future change reddens a cell instead of drifting. |
docs/controls.md §Command policy scope; command_validator.py::_split_local_remote |
Partial - stated, not hidden |
| Network egress control | "every network connection passes through a policy check before it leaves the sandbox" (README:25) | Deny-by-default against an operator allowlist; a missing or empty list resolves to no hosts allowed, never to "unrestricted". DNS is a policy-enforcing proxy: a hostname resolves if and only if that exact name is an entry. The enforcing proxy is Docker's, and Venya registers the per-host rules into it. | docs/controls.md §Egress; egress_filter.py::DEFAULT_ALLOWLIST_PATH; test_egress_filter.py::TestReadAllowlist::test_missing_file_returns_empty |
Shipped, fail-closed |
| What egress control does not do | Not claimed in their README either | It bounds destinations, not content. It is not a data-loss-prevention control over what an allowlisted host is sent; a deny lands one layer after the tunnel is established, so destination names can leave the sandbox even when payload is blocked. | docs/controls.md §Egress (limits paragraph); docs/architecture.md §Sandbox and egress (two consequences) |
Open problem |
| Agents never hold real credentials | "Agents never see real credentials; OpenShell adds them only to requests bound for approved endpoints" (README:25) | Same goal, different mechanism. Values are wrapped server-side, relayed over mutual TLS, unwrapped host-side by the executor, written to a per-session tmpfs file (0400, zeroed after the run) and exposed inside the sandbox at /run/secrets/venya/<id>. stdout/stderr pass a two-stage redaction filter; a filter failure returns nothing raw. The caller - human or model - sees the result and not the value. |
docs/architecture.md §Secret lifecycle (zero-knowledge injection); docs/faq.md "Can the AI agent extract secrets..."; filter.rs::filter_output |
Shipped |
| Human review of a disclosure, not just a login | Policy changes wait for human review (README:26) | Reading a secret value is a separate deliberate act: it requires a single-use elevation token produced by a fresh hardware-key ceremony. A denied attempt is audit-logged and does not consume the token. | docs/auditor-role.md; docs/architecture.md §Secret lifecycle step 1 |
Shipped |
| Formal verification of a policy change before it applies | "formal verification to flag risky new access it would grant... so those changes wait for human review" (README:26) | Venya has no prover. The human gate is real but it reviews a credential ceremony and a session, not a computed diff of what a new policy would allow. | Nothing to check - this is an absence | Not shipped - OpenShell is ahead here |
| Service identity between components | Gateway/supervisor architecture (README:28) | Mutual TLS in both directions. Executor calls are validated against the configured CA and the CN must name a registered executor; the core dials executors' relay listeners with its own client certificate against a CN allowlist, an empty allowlist refuses to bind, and a CN mismatch ends the handshake. | docs/architecture.md §Trust and CA layout (relay CN contract); middleware/auth.py::_validate_executor_mtls |
Shipped |
| Revocation of a compromised node | Not a stated capability in their README | Executor leaves are issued with a 30-day validity and a revocation list is polled; revocation state is read fail-closed, so a stale or unavailable list refuses the request rather than asserting "not revoked". The core's own dial consults a CRL at the TLS layer. | docs/controls.md §Executor identity and the revocation plane; ca.py::EXECUTOR_VALIDITY_DAYS; revocation_read.py::REVOCATION_UNAVAILABLE_DETAIL |
Shipped, with a known gap |
| How fast revocation lands | - | Revocation itself lands within about a minute - except a copied administrator credential, which stays usable until it expires, up to one hour. The published entry says so, and names the ticket behind it. | docs/beta-known-limitations.md, "A copied administrator credential stays usable until it expires" |
Partial - disclosed |
| Audit trail an operator can be held to | Not a stated capability in their README | Append-only where it matters: the application identity gets blanket DML and then REVOKE UPDATE, DELETE ON audit_events runs last, so the revoke wins. Review scope is enforced server-side, so non-privileged callers see only their own events. |
docs/controls.md §Audit recording; 031_audit_append_only_grants.py::REVOKE_AUDIT_SQL; routes/audit.py::audit_list |
Shipped |
| How strong that audit guarantee is | - | It is protection against the application path, not against a PostgreSQL superuser on the host. There is no hash chain and no per-record signature, so "tamper-evident" would be a stronger claim than what ships - and the documentation deliberately does not use it. | docs/controls.md, "Limits a reader should not infer past" |
Shipped, scoped |
| Alerting / SIEM export on the record | Observability surface for the gateway (docs site) | Nothing ships. The trail is queryable and forwarded to the core over CA-mandatory HTTPS; there is no notifier, webhook or collector format in the tree. Listed under "Not verified here" so the absence is legible rather than implied. | docs/controls.md §Not verified here |
Not shipped |
| Secrets unreadable to the service itself | Not a stated capability in their README | Envelope encryption: a random DEK per secret wrapped by the KEK with AES-256-KW (RFC 5649), the payload itself ChaCha20-Poly1305. Plaintext never persists, and listings return metadata only. | docs/architecture.md §Secret lifecycle step 1; docs/faq.md "What happens if the core is compromised?" |
Shipped |
| Key custody that no single holder can spend | Not a stated capability in their README | The CA key is encrypted at rest, and off-site custody can be split with Shamir's Secret Sharing so no single backup artifact reconstructs it; recovery is a deliberate operator-present break-glass ceremony. | docs/architecture.md §Authentication and sessions ("Recovery"); docs/BACKUPS.md; venya admin split-ca-key in docs/cli-reference.md |
Shipped |
| Separation between the agent and the thing that enforces policy | BlueField-class hardware firewall so agents cannot modify their own policies (a claim described in the HN thread, not in the README) | Venya gets a similar result from a different place: policy and secrets live on the core, the core's admin plane needs a separate client certificate chained to the per-install Admin CA, and the human plane needs a hardware key. An agent's command path cannot reach either. | docs/architecture.md §Trust and CA layout; middleware/auth.py::_validate_admin_mtls |
Shipped |
| Role separation for reviewers | Not a stated capability in their README | A dedicated auditor tier: read visibility across secrets, roles and executors (metadata) plus the full audit log, with an affirmative deny on secret values - enforced at the plaintext chokepoint, refused before any elevation token is consumed. | docs/auditor-role.md; dependencies.py::auditor_only_permissions |
Shipped |
| Telemetry leaving your machine | "OpenShell collects anonymous telemetry, limited to operational categories and counts" - on by default, disabled by an env var or compiled out (README:87) | Venya sends no operational data anywhere. The only metrics surface is a Prometheus endpoint bound to the core's own loopback, and its address is not configurable - unset the port and it binds nothing. The documented outbound paths are to your executors, to Docker Hub for the sandbox template, and to your targets. | docs/FIREWALL.md (port 10011 row; outbound rows); docs/deployment-config.md §metrics port |
Shipped |
| Credential material in transit | Not stated in their README | Redaction covers stdout/stderr. The command string itself is recorded and forwarded unmasked by design, so a secret interpolated into argv lands in audit and journal sinks - the docs name this and give the blessed file-injection shape instead. | docs/architecture.md "Operator rule (load-bearing)"; docs/controls.md §Secret shapes |
Partial - documented |
| Supported platforms | Linux, macOS on Apple Silicon, Windows with WSL 2 (experimental), needing Docker, Podman or host virtualization (README:32) | Ubuntu 24.04 LTS is the tested core and executor target. The workstation CLI runs on Linux and macOS, and Windows 10 1903+/11 via a PowerShell installer; hardware-key ceremonies on Windows need an interactive desktop session. | docs/faq.md "What platforms are supported?" |
Narrower - stated |
| GPU / accelerator sandboxing | Sandbox images, runtimes, GPUs and lifecycle (README:45) | Not a Venya surface. Venya brokers credentials and commands; it does not manage accelerator-bearing sandbox images. | Nothing to check - this is an absence | Out of scope |
| Kubernetes / Helm deployment of the control plane | Deploy the gateway with Helm; your CNI must enforce NetworkPolicy (README:49) | No Kubernetes path ships. The core is a systemd service and single-node; HA (PostgreSQL replication plus CA material) is a beta track item. | docs/faq.md "Is there Docker?", "How does it scale?"; docs/architecture.md §Deployment shape |
Not shipped |
| SDK surface for applications | Python, TypeScript, Go and Rust SDKs (README:68-73) | Venya's integration surfaces are a REST API, a workstation CLI, and an MCP stdio server exposing exactly four tools (list_secrets, list_executors, run_command, get_audit). No language SDKs ship. |
docs/architecture.md §Repository layout (packages/mcp) |
Not shipped |
| Install integrity | curl -LsSf .../install.sh | sh (README:35) |
Venya's documented install is also a piped script run as root, so this page will not claim a moral victory. What ships on top of it: the payload tarball is SHA-256-gated and fail-closed - a pin is verified strictly, a pin is required on any non-https origin, and unset on https the installer fetches the same-origin sidecar and aborts on mismatch. There is no default encryption passphrase, and the passphrase a piped install must supply has a length floor enforced before the installer changes anything on the host. | docs/installation.md §1 (the curl line; "The installer is SHA-256-gated and fail-closed") |
Shipped, same shape |
| License | Apache-2.0 (README:11) | Source available under BUSL 1.1 during the commercial window, not OSI open source. Free to use, modify and run in production below US $10M consolidated revenue and for non-competing use; each version converts to MPL 2.0 four years after its first public distribution. | docs/faq.md "Is Venya open source?"; LICENSE |
Stated plainly |
| Agent-facing operating contract | Public skills that teach an agent to drive the CLI (README:56-62) | Venya publishes an instruction block meant to be pasted into an agent's own rules file (docs/agent-prompts.md) and an operator contract that states the hard rules - including that [REDACTED:<id>] markers are the system working and must not be worked around. |
docs/agent-prompts.md; docs/agents.md §Hard rules |
Shipped |
Read down the status column before you read the prose. Venya is ahead on the human trust path - hardware-key authorization for sessions, a second ceremony for reading a value, an auditor tier that is denied values by construction - and ahead on the record: identity in both directions, fail-closed revocation, and an audit trail the database will not let the application rewrite. OpenShell is ahead on confinement depth (kernel policy on file access and syscalls) and on policy analysis (a prover that says what a change would allow before a person approves it), and it has a broader platform and deployment surface today. Those are real differences, and a comparison that hid them would not be worth reading.
What Venya ships that has no counterpart in OpenShell's published design
The list below is one-sided by construction: each row is a Venya capability with an anchor you can re-derive from our tree, paired with the honest sentence about the other side - no such mechanism appears in their published design. That sentence is about their README, which is the document we read. A README is not a product boundary, and we do not claim to have audited their internals; see Not covered by their published material for what this page therefore cannot say. The command that checks any Venya row is printed once, in How to check any row on this page.
| Venya capability | What it means in operation | Their published design | Anchor in our tree |
|---|---|---|---|
| Human hardware key, every session | A session exists only after the server verifies a WebAuthn/FIDO2 assertion. There is no password pathway for humans in the product at all - not a disabled one, none. | No such mechanism appears in their published design (zero mentions of FIDO2, WebAuthn, hardware keys, passkeys or multi-factor in their README) | fido2/manager.py::finish_authentication; docs/faq.md "Can I use passwords or TOTP?" |
| A second ceremony just to read a value | Disclosure of a secret value is a separate deliberate act gated by a single-use elevation token. A refused attempt is audit-logged and does not burn the token. | No such mechanism appears in their published design | packages/core/src/core/iam/models.py::ElevationToken; docs/auditor-role.md |
| An auditor who sees everything and holds nothing | A third permission tier (read, read-write, auditor, plus the seeded admin) with an affirmative deny on secret values, enforced at the plaintext chokepoint rather than by UI convention. | No role or permission-tier model appears in their published design | packages/server/src/server/dependencies.py::auditor_only_permissions; docs/auditor-role.md |
| Append-only audit, enforced by the database | The application identity gets blanket DML and then REVOKE UPDATE, DELETE ON audit_events runs last, so the revoke wins. Scope is enforced server-side: non-privileged callers see only their own events. |
No audit-trail mechanism appears in their published design (the word does not occur in their README) | packages/core/alembic/versions/031_audit_append_only_grants.py::REVOKE_AUDIT_SQL; packages/server/src/server/routes/audit.py::audit_list |
| Fail-closed revocation | A stale or unavailable revocation list refuses the request instead of asserting "not revoked", and the core's own dial-out consults a CRL at the TLS layer. | No revocation mechanism appears in their published design | packages/server/src/server/revocation_read.py::REVOCATION_UNAVAILABLE_DETAIL; routes/executors.py::_build_relay_ssl_context |
| Certificates as machine identity, in both directions | Executors present X.509 client certificates issued by your own core CA (30-day leaf, single-use hashed enrollment token of about 30 minutes); the core dials executors with its own relay certificate against a CN allowlist that refuses to bind if empty. | No certificate-based identity model appears in their published design | packages/server/src/server/ca.py::EXECUTOR_VALIDITY_DAYS; docs/architecture.md §Trust and CA layout |
| A separate door for the admin plane | Admin API paths additionally require a client certificate chained to a per-install Admin CA, on top of the token door. An agent's command path reaches neither it nor the CA material. | Not covered in their published design | middleware/auth.py::_validate_admin_mtls; docs/installation.md ("admin mTLS enforcement") |
| Secrets unreadable to the service itself | Envelope encryption - a random DEK per secret wrapped with AES-256-KW, the payload ChaCha20-Poly1305. Plaintext never persists; listings and admin surfaces return metadata only. | No at-rest encryption model appears in their published design | docs/architecture.md §Secret lifecycle step 1; docs/faq.md "What happens if the core is compromised?" |
| Key custody no single holder can spend | The CA key is encrypted at rest and can be Shamir-split K-of-N for off-site custody, with a separate operator-present break-glass restore ceremony. | No key-custody or split-secret model appears in their published design | packages/cli/src/venya_cli/cli.py (admin split-ca-key); docs/BACKUPS.md |
| Deny-by-default egress, including names | A missing or empty allowlist resolves to no hosts allowed - never to "unrestricted" - and DNS is a policy-enforcing proxy, so a hostname resolves if and only if that exact name is an entry. | Their design puts a policy check on every connection (README:25); the fail-closed-on-empty-list and name-resolution properties are not stated in their published material | packages/executor/src/executor/egress_filter.py::DEFAULT_ALLOWLIST_PATH; packages/executor/tests/test_egress_filter.py::TestReadAllowlist::test_missing_file_returns_empty |
| Per-command policy, refused structurally | A deny-by-default blocklist is scanned into every command (16 named commands in the shipped default list), binaries must resolve into trusted directories, and pipes, redirects and metacharacters are refused per element before the pattern layer runs - with one ruled exception, documented. | Their enforcement point is the kernel and the connection (README:25); a per-command text gate of this shape is not described in their published design | command_validator.py::DEFAULT_DANGEROUS_PATTERNS, ::DEFAULT_TRUSTED_PATHS; executor.py::_validate_command_structure |
| Two-stage output redaction that fails closed | A compiled Rust filter masks secret material in stdout/stderr, then a definitive server-side filter re-screens the unfiltered bytes with the store's own knowledge. If stage two cannot identify the session, the caller keeps the masked output - a filter failure never returns raw bytes. | No output-redaction stage appears in their published design | packages/executor/src/executor/filter.py::filter_output; docs/architecture.md §Secret lifecycle step 4 |
| A closed set of ways a secret may be consumed | Consumption shapes are a declared set with an empty pending-mechanism set, so every built-in a caller can name has working code behind it; an unknown shape is stored and warned, never executed. | Not covered in their published design | routes/secrets.py::BUILTIN_SHAPES, ::MECHANISM_PENDING_SHAPES; docs/secret-shapes.md |
| Authorization that expires on a clock | 15-minute idle window, 4-hour hard cap, 5-minute access tokens, and an expiry error that tells an LLM client to ask the human - because an agent cannot renew a human's authorization. | No session-cap model appears in their published design | docs/architecture.md §Authentication and sessions; docs/faq.md "Why do sessions expire so aggressively?" |
| Rate limiting on the doors that matter | Authentication endpoints refuse beyond 20 requests per minute per IP, with 429 and Retry-After, and the counters persist in the database rather than in process memory. |
Not covered in their published design | packages/server/src/server/middleware/rate_limit.py::auth_requests_per_minute |
| No footprint on the machines you manage | Venya installs nothing on target hosts. Executors reach them over SSH with operator-provided credentials, which are themselves secrets injected per command. | Different model: their sandboxes host the agents; our executors drive already-existing hosts | docs/architecture.md §Deployment shape ("Targets are untouched"); docs/faq.md "Does Venya install anything on my target hosts?" |
| Agent integration on an open protocol | An MCP stdio server exposing exactly four tools - list_secrets (metadata only), list_executors, run_command, get_audit - so any MCP client works without a vendor-specific SDK. |
Their published integration surface is an npx skills add skill pack plus four language SDKs (README:56-73) - a different and broader choice than ours |
docs/architecture.md §Repository layout (packages/mcp) |
| Claims held to the tree by a test | Our control documentation is parsed by a test that resolves every file::symbol cite against the commit it records and fails when a symbol stops resolving - so a stale claim becomes a build failure, not a silent page. |
Not covered in their published design | packages/server/tests/test_controls_doc_cite_interlock.py; docs/controls.md §What this page is for |
| A published list of what does not work yet | docs/beta-known-limitations.md is a maintained document whose rule is that a row is deleted when the limitation stops being true, and each entry names the tracked issue behind it. |
Their README publishes a roadmap board and an upgrade guide; a dated limitation list of this shape is not among what they publish | docs/beta-known-limitations.md §"How this list is maintained" |
Read this list as breadth of the plane each product governs, not as a score. OpenShell publishes a kernel, a network gate and a prover. Venya publishes an identity model, a custody model, a disclosure ceremony, a record that cannot be rewritten, and a redaction stage. Most of what is above exists because our product sits between a person and a credential, which is a place their published design does not describe itself as standing.
Not covered by their published material
This section exists so the previous one cannot be read as a scorecard. It lists what this page cannot state, and why.
| Question a reader might ask | What we can say from what they publish |
|---|---|
| Does OpenShell have an audit trail? | Their README does not mention one. Their docs site has an observability section we have not audited. We state neither yes nor no. |
| Does OpenShell have human approval for a disclosure? | Their README describes human review of risky policy changes (line 26). It does not describe a per-value disclosure ceremony or a hardware key. We do not claim their software cannot do it - we claim their published design does not say it does. |
| Does OpenShell encrypt stored secrets? | Not covered in their published material. Their Providers section describes credentials that work only at approved endpoints (line 45); how those are stored at rest is not in the document we read. |
| Does OpenShell support roles, or a read-only reviewer? | Not covered in their published material. |
| Does OpenShell have revocation? | Not covered in their published material. |
| How good is their kernel enforcement, really? | Unknown to us. We have not read their source and will not grade it from a README - in either direction. |
| Is their formal verification load-bearing? | Their README says it flags risky new access before it is applied (line 26). What the prover proves, and against what model, is on their docs site and outside what we verified here. |
| Which product is more secure overall? | This page does not answer that, and a page that did would be guessing. It answers a narrower question: which mechanisms each one publishes, and where you can check them. |
Everything on this page about OpenShell comes from one file - their project README - fetched on
30 October 2026 from main at commit 17eda52d (95 lines, sha256
55cceb79...) and quoted with its line number. Line numbers are a property of the file we
read, not of their repository: that README gained two lines at line 41 on 26 October 2026, which moved
every cite below it by two, so a number quoted here is true of the snapshot named above. We did not read
their source, their docs site beyond the links the README carries, or their issue tracker. If a row above
misreads them, say so at info@tabith.com and we will correct the row in the open, with the date.
Concerns raised about products in this class, and where Venya stands on each
A thread on Hacker News about OpenShell collected a set of objections that apply to agent infrastructure generally. Each one below is the concern in the commenter's own words, kept short, with the comment it came from, and then what Venya actually does. We are not answering them as criticism of NVIDIA; these are the questions we get asked about our own product, and the honest answers are the same shape.
"The more access you give the agent, the more capable it becomes - you cannot have both"
"the more access you give the agent the more capable it becomes. You can't have your cake and eat it... the blurb reads like it can do it all, but now secure. That can't be true." smallnix, HN item 50201244
Agreed, and Venya does not claim otherwise. The trade is not removed, it is moved: what the agent gets is the ability to cause an authenticated action, not the ability to hold the thing that authorizes it. Values are injected inside the sandbox and output comes back redacted, so the useful half of the access stays and the leakable half does not. The limits on that are named in the same documents: the command string itself is recorded unmasked, and the redaction is a defense that assumes the sandbox boundary holds.
Allowlisting destinations does not stop data leaving to a permitted host
"We can restrict network to trusted domains, but there's always a chance an agent could be extra slippery especially if prompt injected and doing something like pushing data out a few characters at a time." fennecbutt, HN item 50201432
"If you can make any request to the outside world you can exfiltrate data, period." epolanski, HN item 50201532
This is true and Venya does not solve it. Our egress control is fail-closed on
destinations and it fails closed when the allowlist is missing or empty, but it is not a
data-loss-prevention control over what an allowlisted host is sent, and the destination
name itself can leave the sandbox even when the payload is blocked. What Venya adds to
that picture is attribution and containment rather than a claim: every command is
attributed to the human whose key authorized the session, secret material in output is
replaced with [REDACTED:...] by a compiled filter and then re-screened
server-side with the store's own knowledge, and a filter failure returns nothing raw.
If your threat model includes a determined slow-dribble exfiltration over an approved
destination, the honest answer is that nobody in this product class ships a control that
stops it, and you should assume it and scope what you allowlist accordingly.
"You'd want to know what it did even if you don't catch it"
"It seems like some kind of network logging would be useful? Even if you don't catch it, you'd want to know what it did." skybrian, HN item 50202264
Shipped: every step records actor, command string, executor id, secret ids (never values) and timestamps, in a trail the database will not let the application update or delete, with review scope enforced server-side. Not shipped: alerting, SIEM or any collector format. Today the record is queryable by a human and by an auditor role, and nothing will page you.
Telemetry on by default; "anonymous" is a word people do not accept
"Taking default telemetry is insane." dangoodmanUT, HN item 50199137
"There is no such thing [as anonymity in 2026]... the documentation listing the collected telemetry uses weasel words like 'such as' rather than providing a comprehensive list." lcampbell, HN item 50200078
Venya collects nothing operational and sends it to us. There is no default-on beacon
to argue about and no env var to hunt for: the metrics endpoint that does exist is bound to
the core's own loopback, and its address is not configurable precisely because the endpoint
is unauthenticated — unset the port and it binds nothing. docs/FIREWALL.md
enumerates every inbound and outbound path in a deployment, and no operational reporting to
Tabith appears anywhere in it. What leaves your network is a fetch at install time
(toolchains and packages, from your release origin), a sandbox template pull from Docker
Hub, and your own traffic to your targets.
Installing a security layer with a root pipe, and letting the agent do it
"Looks neat. I'll give Claude root access so it can set it up." spider-mario, HN item 50199498
"Or don't give it root access and in the morning you'll have both this and a ready-to-use root exploit!" yoavm, HN item 50199716
Venya's documented install is the same shape as OpenShell's - a piped script run as root - so this is not a row where we are better. What we ship around it is integrity and least privilege: the payload tarball is hash-gated and fail-closed, the encryption passphrase has no default and a length floor enforced before the installer mutates anything, and after installation the agent's command path reaches neither the admin plane nor the CA material, because those need a client certificate chained to the Admin CA plus a hardware-key ceremony. The joke in that thread is a real failure mode, and the answer to it is that an agent should not be the one installing the thing that gates it.
Agents collaborating to exceed what any single agent is allowed
"Apparently agents will collude to break out of their individual sandboxes by delegating tasks to other agents that have the required permissions... you need them to coordinate on their tasks." prennert, HN item 50204990
"Any workflow that has both an input and an output will complete the Lethal Trifecta as a whole, but no single agent does by itself." smashed, HN item 50201845
Venya does not have a collective-permission view of a fleet and does not claim to. What limits the shape today is that capability is not what gets delegated: a second agent still needs its own session, and a session still needs a human's key. Secrets are scoped to roles, so "what can this executor reach" is a per-identity question rather than a per-model one, and every command lands in the audit trail attributed to a person. If you are building a fleet where agent A hands tainted content to agent B which then holds the private data and the network, Venya does not detect that for you - tag-and-monitor designs in that thread are ahead of what anyone here ships.
Isolation is only worth something if it holds against the platform you run on
"most people running containers are running a default docker/containerd setup, which does not actually isolate you from anything at all" devmor, HN item 50203149
"I just want the whole harness inside a sandbox - ideally, a full VM" zmmmmm, HN item 50202392
Venya runs commands in microVMs rather than in a shared-kernel container, and the
daemon that orchestrates them is seccomp-confined without CAP_IPC_LOCK. It
does not, however, put your agent's harness in a VM - that stays on your workstation or
wherever you run it, which is exactly the camp the second commenter is in. Our bet is a
different one: the harness is the part you can replace, so the trust is anchored on the
credential and the ceremony rather than on confining the model's own process.
"Almost too pedantic" - and whether this is only for large enterprises
"the level of control is cool, almost too pedantic. It likely is only particularly useful for very nuanced enterprise requirements" dangoodmanUT, HN item 50199137
"as isolation increases, so does friction, and then of course capabilities" amanfromhere, HN item 50204422
Fair, and it is the part of our own design we work on. The ceremony cost is real: a
hardware key is required to open a session and again to read a value. Two things make it
cheaper than it sounds - a session covers a window rather than a command (15-minute idle,
4-hour cap), and a command that needs a credential does not need a separate approval per
call, because the value is injected by the executor inside the sandbox. The rough edges
are published, not hidden: docs/beta-known-limitations.md currently carries
an entry for administrator commands that asked for a ceremony they did not need, and one
for sshpass with a redirect aimed at a remote sudo -S not
delivering the password.
Vendor lock-in and platform dependence
"Isn't using a sandbox provided by them giving you more restrictions though?... you're forced to move at their pace" fennecbutt, HN item 50200978
"Now if Microsoft will start addressing the fact that VSCode remote ssh exposes your host to attack from the sandbox..." Rapzid, HN item 50202661
Venya has a dependency in this exact place and says so on its own install page: the
sandbox is Docker Sandboxes (sbx), a proprietary product of Docker, Inc.,
fetched from Docker's repository, requiring a Docker account and governed by Docker's
Subscription Service Agreement. What Venya is not is a cloud: the core runs on your
infrastructure, with your CA, and nothing in the architecture calls a service we operate.
Agent-side, the integration point is MCP - the same protocol Claude Code, Cursor and any
other client speak - so the harness is not part of the lock either.
Whether a hardware maker will maintain the software
"My expectation is that it will be poorly maintained; nvidia is not a software company." esafak, HN item 50199437
A question about them, and a fair one, so here is the mechanism on our side instead:
Venya's control documentation is guarded by a test. docs/controls.md is
parsed by packages/server/tests/test_controls_doc_cite_interlock.py, which
resolves every file::symbol cite against the commit it records and fails the
build when a symbol stops resolving - so a claim that goes stale is a red test rather
than a silent page. That is the only honest answer to "how do I know what you say about
your own code stays true": you make the statement and the tree disagree expensively.
Naming, and claiming your own safety in the first line
"Is it fair to immediately get the ick from the name and the description... 'Open' and 'Shell' and just calling something private and safe out the box genuinely makes me think it's likely to fail at all of those claims." jrm4, HN item 50199960
The instinct is sound and it applies to us. "Safe" and "secure" are not load-bearing words in this page or in our documentation - the control page's own first line is "Alignment, not certification", it says the word it supports is alignment and the word it never claims is certified, and there is a whole document whose job is to list what does not work yet. Anyone selling a runtime as safe, in a sentence, before a single mechanism, is inviting exactly the reaction that thread had.
Trusting the model's judgement instead of the boundary
"Critically, in the intended approach for this, Claude itself (the harness) runs outside the sandbox. Their approach means you trust Claude is perfect, just the commands it runs need isolation." zmmmmm, HN item 50202392
This is the sharpest architectural objection in the thread and it is worth answering directly, because Venya is deliberately in the "do not trust the model" camp at the specific boundary that matters to us. Nothing about a model's judgement is load-bearing for keeping a credential out of a context: the value never enters it, a session expires on a clock an agent cannot extend, reading a value needs a physical ceremony, and the deny-by-default allowlist resolves to no hosts when it is empty. We still trust the sandbox boundary to hold, and we say so - that is the assumption the redaction layer is built on.
Problems neither product has solved
The most useful part of that thread was not the criticism of OpenShell - it was the list of problems the commenters agreed nobody in this class has an answer to. We would rather publish the list than pretend past it.
| Problem | Where Venya is |
|---|---|
| Exfiltration through an allowlisted destination, slowly and in small pieces | Not solved by us and not solved by anyone in that thread. Destination control plus attribution plus output redaction, and nothing that stops a permitted host being permitted. |
| Content-level checks: is what left the sandbox actually secret? | Only for values the store knows. Arbitrary private data the agent was given but never held a credential for is outside the filter's knowledge. |
| Collective permission across a fleet, and collusion by delegation | Not shipped - per-session, per-identity scoping only. No fleet-wide permission-set monitor. |
| Deciding in advance everything an agent legitimately needs | Not shipped. The thread's most practical comment: "the hardest is not setting up the security rules, but knowing in advance everything your agent needs access to" (HN item 50208824). OpenShell's advisor and prover are aimed at exactly this, and Venya has neither. |
| Alerting when the record shows something wrong | Not shipped - queryable trail, no notifier, no SIEM format. |
| Attestation that a hardware key is the model it claims to be | Not shipped. Registration requests "attestation": "none", so possession of a registered credential ships and device genuineness does not. Some products in this space verify attestation certificate authorities today; ours is a roadmap depth item, not a uniqueness claim. |
| Offline and air-gapped installation | Not shipped as of v0.1.0beta2, the release this comparison was re-run against - the installers fetch toolchains and packages at install time. A local-mirror procedure exists for beta sites and is not packaged yet. |
| Bootstrapping who the first administrator is | Trust-on-first-use today: whoever completes the key ceremony first on a newly initialized core becomes its administrator. The documented mitigation is to initialize on a network you control before you expose it. |
How to check any row on this page
Venya's documentation is written so a row is a command, not an assertion. Every control
in docs/controls.md carries the symbol that enforces it, the commit it was
verified at, and the one command that re-derives it. Start from the release tree:
git clone https://github.com/tabith-llc/venya.git cd venya git show v0.1.0beta2:docs/controls.md # what is enforced, with a re-derive command per row git show v0.1.0beta2:docs/architecture.md # secret lifecycle, sandbox and egress, CA layout git show v0.1.0beta2:docs/beta-known-limitations.md # what does not work yet git show v0.1.0beta2:docs/security-landscape.md # the same comparison against 16 other products
The OpenShell side of this page comes from their public README only, and we have kept the quotes short and line-referenced rather than republishing their documentation. The one command that checks our one-sided statements is this - run it against the copy of their README you have, and read the empty result as "not in this document", never as "not in their product":
grep -inE 'fido|webauthn|hardware key|passkey|authenticator|multi-factor|2fa|mfa|audit|revoc|role|encrypt' openshell-readme.md # measured against the copy this page was read from, again on 30 October 2026: zero matches for every term above # the word "human" matches once, at line 26, in "wait for human review" of a policy change
If they ship something that closes a gap listed here, that is worth knowing and we will correct
the row - the honest version of a comparison is a dated one, and this page reflects
Venya v0.1.0beta2 (f20b365) and OpenShell's main README as fetched
on 30 October 2026. The Venya rows were re-run against v0.1.0beta2 on that date: every
file, symbol and document each row cites still exists in that tree, and the limits the rows disclose -
a command blocklist an operator can replace, an audit grant that stops at a database superuser, no
attestation of key genuineness, no prover - are still the limits.
A note on what "verified" means here. Rows marked Shipped mean code enforces the thing and a command re-derives it from this tree. They do not mean an independent assessor examined anything, and they do not mean a claim was observed on a running fleet - where a property is unit-asserted but not physically captured, our own documentation says so in the row. That distinction is the reason this page exists in the form it does.
The short version
Start with the human. Venya requires a physical security key to open a session and a second ceremony to read a value, and no such mechanism appears anywhere in OpenShell's published design. That single fact decides what the rest of this page is: if you need a person's key inside every privileged action, with a record the database will not let the application rewrite, that is Venya. If you need an agent fleet's kernel-level reach confined - files, syscalls, per-connection checks, and a formal argument about what a policy change would allow before anyone approves it - that is OpenShell, and Venya does not do it.
Both can be true at once: OpenShell is a stronger sandbox, and Venya is a stronger credential and accountability plane. Neither is a finished product, and neither should be trusted on a sentence.